package com.gitee.sidihuo.sse.other;

import lombok.extern.slf4j.Slf4j;
import okhttp3.*;
import org.springframework.util.StopWatch;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;

/**
 * 非sse的okhttp3的websocket请求
 */
@Slf4j
public class OkHttpWebSocketInvoker {

    public static List<String> invoke(String requestJson, String url) {
        return invoke(requestJson, url, System.currentTimeMillis() + "");
    }

    public static List<String> invoke(String requestJson, String url, String requestNo) {
        log.info("OkHttpWebSocket invoke url = {} requestNo = {} requestJson = {}", url, requestNo, requestJson);
        Request request = new Request.Builder().url(url).build();
        CountDownLatch countDownLatch = new CountDownLatch(1);
        List<String> messages = new ArrayList<>();
        OkHttpClient okHttpClient = new OkHttpClient.Builder().build();
        WebSocket webSocket = okHttpClient.newWebSocket(request, new WebSocketListener() {
            @Override
            public void onMessage(WebSocket webSocket, String text) {
                super.onMessage(webSocket, text);
                log.info("OkHttpWebSocket requestNo = {} text = {}", requestNo, text);
                messages.add(text);
            }

            @Override
            public void onClosed(WebSocket webSocket, int code, String reason) {
                super.onClosed(webSocket, code, reason);
                log.info("OkHttpWebSocket onClosed requestNo = {} reason = {} code = {}", requestNo, reason, code);
                countDownLatch.countDown();
            }

            @Override
            public void onClosing(WebSocket webSocket, int code, String reason) {
                super.onClosing(webSocket, code, reason);
                log.info("OkHttpWebSocket onClosing requestNo = {} code = {} reason = {} ", requestNo, code, reason);
                countDownLatch.countDown();
            }

            @Override
            public void onFailure(WebSocket webSocket, Throwable t, Response response) {
                countDownLatch.countDown();
                super.onFailure(webSocket, t, response);
                log.warn("OkHttpWebSocket onFailure requestNo = {} ", requestNo, t);
            }

            @Override
            public void onOpen(WebSocket webSocket, Response response) {
                super.onOpen(webSocket, response);
                log.info("OkHttpWebSocket onOpen requestNo = {} ", requestNo);
            }
        });

        StopWatch stopWatch = new StopWatch();
        stopWatch.start();
        boolean send = false;
        try {
            send = webSocket.send(requestJson);
        } catch (Throwable t) {
            log.warn("OkHttpWebSocket send failed send = {} requestNo = {}", send, requestNo, t);
        }
        //log.info("OkHttpWebSocket send = {} requestNo = {}  ", send, requestNo);
        boolean await = false;
        try {
            await = countDownLatch.await(5, TimeUnit.MINUTES);
        } catch (InterruptedException e) {
            log.warn("OkHttpWebSocket countDownLatch await InterruptedException {}", requestNo, e);
        }
        stopWatch.stop();
        double totalTimeSeconds = stopWatch.getTotalTimeSeconds();
        if (await) {
            log.info("OkHttpWebSocket end countDownLatch finished {} totalTimeSeconds = {}", requestNo, totalTimeSeconds);
        } else {
            log.warn("OkHttpWebSocket end countDownLatch failed {} totalTimeSeconds = {}", requestNo, totalTimeSeconds);
        }
        return messages;
    }

}
